package cn.biplam.front.template.control.table;

import java.util.ArrayList;

import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.KvMap;
import cn.biplam.common.wrapper.UserInfo;
import cn.biplam.front.callback.CallBack;
import cn.biplam.front.html.base.HtmlWindow;
import cn.biplam.front.html.base.Const.Window_Event;
import cn.biplam.front.htmlscript.script.AjxScript.Level;
import cn.biplam.front.template.control.rfFlowTable.callback.content.IndexColCallback;
/**
 * 	流式布局表的表格属性类<br>
 * <ul>用法：
 *  <ul> 创建表格属性类
 *  	<li> new TablePropertys("应用系统路径") 
 *  </ul>
 *  <ul>当列的数据源为自动绑定数据集时设置列信息
 *  	<li> this.putCol("列对应的数据集字段名","列类型","列标题") 
 *  </ul>
 *  <ul> 当列的数据源为外部传入时设置列信息
 *  	<li> this.putCol("列名","列类型","列标题","列内容") 
 *  </ul>
 *   *  <ul> 当列的数据源为外部传入回调器设置列信息
 *  	<li> this.putCol("列名","列类型","列标题","列回调器") 
 *  </ul>
 *  <ul> 设置列事件
 *  	<li> this.setColAction("列名","列窗口事件","列事件需要绑定的脚本类型","事件动作ID","目标容器ID") 
 *  </ul>
 * @author XiaoRuxing Oct 23, 20099:38:47 AM
 * @version 1.0
 */
public class TablePropertys extends TableScript{

	/** 存储表列唯一列名，列名为列对应数据集字段名，当列数据不来自于数据集时自定义列名 */
	private ArrayList<String> tableColField;
	/** 表列类型 */
	private ArrayList<Col_Content_Type> tableColType;

	/** 列标题 */
	private ArrayList<String> tableColTitle;

	/** 存储单元格内容为外部传入的对象,如按钮,key为行名,value为传入对象 */
	private KvMap<String,HtmlWindow[]> extentColumn;

	/** 存储单元格内容为是否为外部传入 */
	private KvMap<String,Boolean> isExtent;

	/**存储列事件, key为列名,value为单元格对应事件类型 */
	private KvMap<String,ArrayList<Window_Event>> columnEvent;
	/**存储列事件目标容器, key为列名,value为单元格事件对应目标容器ID,如果为空则默认目标为本容器 */
	private KvMap<String,ArrayList<String>> eventTarget;
	/**存储列事件对应脚本函数, key为列名,value为单元格事件要调用的js脚本函数 */
	private KvMap<String,ArrayList<Action_Type>> eventFunction;
	/** 存储列事件对应ActID,kye为表格列名,value为单元格事件对应的actID */
	private KvMap<String,ArrayList<String>> eventAct;
	/** 存储列事件附加参数 */
	private KvMap<String, ArrayList<String[]>> eventOtherParams;
	/** 列单元格对象生成的绑定器 */
	private KvMap<String,CallBack> columnCallBack;
	
	/** 存储是否显示列重复数据 */
	private KvMap<String, Boolean> displayDuplicateCol;
	/** 表格行索引列列名 */
	public final String INDEX_COL_NAME = ".flowTableIncexColName";

	/** 系统路径 */
	private String sHomeUrl;
	/** 用户信息 */
	private UserInfo mUser;
	/** 表格列数 */
	private int colNums;

	
	/** 单元格内容类型 */
	public enum Col_Content_Type{
		/** 普通文本 */
		NAME_TEXT,
		/** 超级连接文本 */
		NAME_ANCHOR,
		/** 短文本描述(只显示4个中文字,超过内容在弹出框中显示) */
		DESC_SHORT_TEXT,
		/** 长文本描述类型 */
		DESC_LONG_TEXT,
		/** 文本描述 */
		DESC_TEXT,
		/** 短超级链接描述(只显示4个中文字,超过内容在弹出框中显示) */
		DESC_SHORT_ANCHOR,
		/** 长文本超级链接描述 */
		DESC_LONG_ANCHOR,
		/** 超级连接描述 */
		DESC_ANCHOR,
		/** 按钮 */
		BUTTON,
		/** 复选框 */
		CHECKBOX,
		/** 下拉框 */
		SELECT,
		/** 单选框 */
		RADIO,
		/** 单选框组 */
		RAIDO_GROUP,
		/** 输入框 */
		INPUT_TEXT,
		/** 多行文本输入框 */
		INPUT_TEXT_AREA,
		/** 隐藏input */
		INPUT_HIDDEN;
	}

	/** 长描述类型的单元格内容最大长度 */
	public static final String sLongDescLength="240";
	/** 描述类型的单元格内容最大长度 */
	public static final String sCellDescLength="148";
	/** 短描述类型的单元格内容最大长度 */
	public static final String sShortDescLength="72";

	/** 表格大小 */
	public enum Table_Size{
		/** 大 */
		BIG("920"),
		/** 一般大 */
		NORMAL("680"),
		/** 小 */
		SMALL("410");
		private String value;
		private Table_Size(String value){this.value=value;}
		public String toString() {return value;}
		public int toInt(){return Integer.valueOf(value);};
	}

	/**
	 * 传入应用系统路径 创建表格属性类
	 * @param sHomeUrl 应用系统路径
	 * @param mUser    用户信息
	 * @throws ErrorMessage
	 */
	public TablePropertys(String sHomeUrl,UserInfo mUser) throws ErrorMessage{
		this.sHomeUrl=sHomeUrl;
		this.mUser = mUser;
		_init();
	}

	/**
	 * 构造方法
	 * @param tableFields    表列唯一列名，列名为列对应数据集字段名，当列数据不来自于数据集时自定义列名
	 * @param tableFieldsType 表列类型
	 * @throws ErrorMessage
	 */
	public TablePropertys(String[] tableFields,Col_Content_Type[] tableFieldsType) throws ErrorMessage{
		this(tableFields,tableFieldsType,null,null,null);
	}

	/**
	 * 构造方法
	 * @param tableFields    表列唯一列名，列名为列对应数据集字段名，当列数据不来自于数据集时自定义列名
	 * @param tableFieldsType 表列类型
	 * @param tableColTitle   表列标题
	 * @throws ErrorMessage
	 */
	public TablePropertys(String[] tableFields,Col_Content_Type[] tableFieldsType,
			String[] tableColTitle) throws ErrorMessage{
		this(tableFields,tableFieldsType,tableColTitle,null,null);
	}

	/**
	 * 构造方法
	 * @param tableFields    表列唯一列名，列名为列对应数据集字段名，当列数据不来自于数据集时自定义列名
	 * @param tableFieldsType 表列类型
	 * @param tableColTitle   表列标题
	 * @param sHomeUrl 应用系统路径
	 * @param mUser    用户信息
	 * @throws ErrorMessage
	 */
	public TablePropertys(String[] tableFields,Col_Content_Type[] tableFieldsType,
			String[] tableColTitle,String sHomeUrl,UserInfo mUser) throws ErrorMessage{
		_init();
		setField(tableFields, tableFieldsType);
		setTitle(tableColTitle);
		_initIsExtend();
		this.sHomeUrl=sHomeUrl;
		this.mUser=mUser;
	}

	/**
	 * 设置列标题，如果列标题数组为空则设置列标题为表列对应字段名
	 * @param tableColTitle 列标题数组
	 * @throws ErrorMessage 
	 */
	public void setTitle(String[] tableColTitle) throws ErrorMessage{
		if(tableColTitle==null){
			this.tableColTitle.addAll(this.tableColField);
		}else{
			TOOLS.stringArrayToList(this.tableColTitle, tableColTitle);
		}
	}

	/**
	 * 设置表格列内容由外部传入回调器时生成时列信息，默认列类型为文本类型
	 * @param sFieldName 列名,列名必须唯一,当表格绑定数据集时为要绑定的数据集列的列名
	 * @param sColTitle  列标题
	 * @throws ErrorMessage
	 */
	public void putCol(String sFieldName,String sColTitle) throws ErrorMessage{
		this.putCol(sFieldName, Col_Content_Type.NAME_TEXT, sColTitle);
	} 

	/**
	 * 设置表格列数据源为数据集时列信息
	 * @param sFieldName 列名 <br>列名必须唯一,列名为要绑定的数据集列的列名
	 * @param sColTitle  列标题
	 * @throws ErrorMessage 
	 */
	public void putCol(Object sFieldName,String sColTitle) throws ErrorMessage{
		putCol(String.valueOf(sFieldName),sColTitle);
	}

	/**
	 * 设置表格列数据源为数据集时列信息
	 * @param sFieldName 列名 <br>列名必须唯一,列名为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @throws ErrorMessage 
	 */
	public void putCol(String sFieldName,Col_Content_Type fieldType,String sColTitle) throws ErrorMessage{
		putCol(sFieldName, fieldType, sColTitle,new HtmlWindow[]{});
	}

	/**
	 * 设置表格列数据源为数据集时列信息
	 * @param sFieldName 列名 <br>列名必须唯一,列名为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @throws ErrorMessage 
	 */
	public void putCol(Object sFieldName,Col_Content_Type fieldType,String sColTitle) throws ErrorMessage{
		putCol(String.valueOf(sFieldName), fieldType, sColTitle);
	}

	/**
	 * 设置表格列内容由外部传入回调器时生成时列信息，默认列类型为文本类型
	 * @param sFieldName 列名,列名必须唯一,当表格绑定数据集时为要绑定的数据集列的列名
	 * @param sColTitle   列标题
	 * @param disRepeat   是否不显示当前列重复数据,要求数据按照当前列排列
	 * @throws ErrorMessage
	 */
	public void putCol(String sFieldName,String sColTitle,boolean disRepeat) throws ErrorMessage{
		this.putCol(sFieldName, Col_Content_Type.NAME_TEXT, sColTitle,disRepeat);
	} 

	/**
	 * 设置表格列数据源为数据集时列信息
	 * @param sFieldName 列名 <br>列名必须唯一,列名为要绑定的数据集列的列名
	 * @param sColTitle  列标题
	 * @param disRepeat  是否不显示当前列重复数据,要求数据按照当前列排列
	 * @throws ErrorMessage 
	 */
	public void putCol(Object sFieldName,String sColTitle,boolean disRepeat) throws ErrorMessage{
		putCol(String.valueOf(sFieldName),sColTitle,disRepeat);
	}

	/**
	 * 设置表格列数据源为数据集时列信息
	 * @param sFieldName 列名 <br>列名必须唯一,列名为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @param disRepeat  是否不显示当前列重复数据,要求数据按照当前列排列
	 * @throws ErrorMessage 
	 */
	public void putCol(String sFieldName,Col_Content_Type fieldType,String sColTitle,boolean disRepeat) throws ErrorMessage{
		putCol(sFieldName, fieldType, sColTitle,disRepeat ,new HtmlWindow[]{});
	}

	/**
	 * 设置表格列数据源为数据集时列信息
	 * @param sFieldName 列名 <br>列名必须唯一,列名为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @param disRepeat  是否不显示当前列重复数据,要求数据按照当前列排列
	 * @throws ErrorMessage 
	 */
	public void putCol(Object sFieldName,Col_Content_Type fieldType,String sColTitle,boolean disRepeat) throws ErrorMessage{
		putCol(String.valueOf(sFieldName), fieldType, sColTitle,disRepeat);
	}

	/**
	 * 设置表格列内容由外部传入回调器时生成时列信息，默认列类型为文本类型
	 * @param sFieldName 列名,列名必须唯一,当表格绑定数据集时为要绑定的数据集列的列名
	 * @param sColTitle  列标题
	 * @param callBack   列绑定器
	 * @throws ErrorMessage
	 */
	public void putCol(Object sFieldName,String sColTitle,CallBack callBack) throws ErrorMessage{
		this.putCol(String.valueOf(sFieldName), Col_Content_Type.NAME_TEXT, sColTitle,callBack);
	} 

	/**
	 * 设置表格列内容由外部传入回调器时生成时列信息
	 * @param sFieldName 列名,列名必须唯一,当表格绑定数据集时为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @param callBack   列绑定器
	 * @throws ErrorMessage 
	 */
	public void putCol(String sFieldName,Col_Content_Type fieldType,String sColTitle,CallBack callBack) throws ErrorMessage{
		this.putCol(sFieldName, fieldType, sColTitle);
		this.setCallBack(sFieldName, callBack);
	}

	/**
	 * 设置表格列内容由外部传入回调器时生成时列信息
	 * @param sFieldName 列名,列名必须唯一,当表格绑定数据集时为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @param callBack   列绑定器
	 * @throws ErrorMessage 
	 */
	public void putCol(Object sFieldName,Col_Content_Type fieldType,String sColTitle,CallBack callBack) throws ErrorMessage{
		this.putCol(String.valueOf(sFieldName), fieldType, sColTitle,callBack);
	}

	/**
	 * 设置表格列为外部传入时列内容
	 * @param sFieldName 列名,列名必须唯一,当表格绑定数据集时为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @param collComponent 列内容(为html对象)
	 * @throws ErrorMessage 
	 */
	public void putCol(String sFieldName,Col_Content_Type fieldType,String sColTitle,HtmlWindow...collComponent) throws ErrorMessage{
		this.putCol(sFieldName, fieldType, sColTitle, false, collComponent);
	}

	/**
	 * 设置列对象动作
	 * @param colName       列名
	 * @param event         需要绑定的window事件 
	 * @param atciontType   对应的ajx动作类型
	 * @param actID         动作ID
	 * @param targetID      目标容器ID
	 * @param otherParams   附加提交参数
	 * @throws ErrorMessage
	 */
	public void setColAction(String colName,Window_Event event,Action_Type atciontType,
			String actID,String targetID,String... otherParams) throws ErrorMessage{
		setFunction(colName, atciontType);
		setAct(colName, actID);
		setEvent(colName, event);
		setTarget(colName, targetID);
		setOtherParams(colName, otherParams);
	}

	/**
	 * 设置列对象动作,默认绑定单元格的点击事件
	 * @param colName       列名
	 * @param atciontType   对应的ajx动作类型
	 * @param actID         动作ID
	 * @param targetID      目标容器ID
	 * @throws ErrorMessage
	 */
	public void setColAction(String colName,Action_Type atciontType,
			String actID,String targetID) throws ErrorMessage{
		this.setColAction(colName, Window_Event.OnClick, atciontType, actID, targetID);
	}

	/**
	 * 设置列对象动作，默认绑定单元格的点击事件，动作的目标容器ID为根据动作类型决定（如prompt弹出和pv弹出）
	 * @param colName       列名
	 * @param atciontType   对应的ajx动作类型
	 * @param actID         动作ID
	 * @throws ErrorMessage
	 */
	public void setColAction(String colName,Action_Type atciontType,
			String actID) throws ErrorMessage{
		this.setColAction(colName, atciontType, actID, null);
	}

	/**
	 * 设置列对象动作为空,在指定列中有多个对象而某个对象的不需要动作时设置
	 * @param colName       列名
	 * @throws ErrorMessage
	 */
	public void setColAction(String colName) throws ErrorMessage{
		this.setColAction(colName, null, null, null);
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为Pr时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName 列名
	 * @param actID   动作ID
	 * @throws ErrorMessage 
	 */
	public void setColActionPr(String colName,String actID) throws ErrorMessage{
		this.setColActionPr(colName,actID,null);
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为Pr时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName 列名
	 * @param actID   动作ID
	 * @param sOtherContainer 其他需要被提交的容器ID
	 * @throws ErrorMessage 
	 */
	public void setColActionPr(String colName,String actID,String sOtherContainer) throws ErrorMessage{
		this.setColAction(colName,Window_Event.OnClick,
				Action_Type.POP_SUBMIT_PR,
				actID,
				null,
				sOtherContainer);
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为P时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName  列名
	 * @param actID    动作ID
	 * @param targetLevel 目标弹出窗口层次
	 * @throws ErrorMessage 
	 */
	public void setColActionP(String colName,String actID,Level targetLevel) throws ErrorMessage{
		this.setColAction(colName,
				Action_Type.POP_SUBMIT_P,
				actID, 
				targetLevel.toString());
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为SP且不刷新父容器时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName      列名
	 * @param actID        动作ID
	 * @param otherParams  附加提交参数,格式：(参数名,参数值) 如 rid,1001
	 * @throws ErrorMessage 
	 */
	public void setColActionSpNoRefreshParent(String colName,String actID,
			String...otherParams) throws ErrorMessage{
		this.setColAction(colName,
				Window_Event.OnClick,
				Action_Type.SP,
				actID,
				null,
				otherParams);
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为SP且刷新父容器时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName      列名
	 * @param actID        动作ID
	 * @param parentCID    父亲容器ID
	 * @param otherParams  附加提交参数,格式：(参数名,参数值) 如 rid,1001
	 * @throws ErrorMessage 
	 */
	public void setColActionSpRefreshParent(String colName,String actID,String parentCID,
			String...otherParams) throws ErrorMessage{
		this.setColAction(colName,
				Window_Event.OnClick,
				Action_Type.SP_REFRESH_PARENT,
				actID,
				parentCID,
				otherParams);
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为PV时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName      列名
	 * @param actID        动作ID
	 * @throws ErrorMessage 
	 */
	public void setColActionPV(String colName,String actID) throws ErrorMessage{
		this.setColAction(colName,
				Window_Event.OnClick,
				Action_Type.POP_SUBMIT_PV,
				actID,
				null);
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为M时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName      列名
	 * @param actID        动作ID
	 * @param targetID     目标容器ID
	 * @throws ErrorMessage 
	 */
	public void setColActionM(String colName,String actID,String targetID) throws ErrorMessage{
		this.setColAction(colName,
				Window_Event.OnClick,
				Action_Type.NONE_POPE_M,
				actID,
				targetID);
	}

	/**
	 *  设置列对象点击事件提交的ajx动作类型为A时列提交信息
	 *  如果列单元格有多个对象按照顺序依次设置各对象的提交动作
	 * @param colName      列名
	 * @param actID        动作ID
	 * @throws ErrorMessage 
	 */
	public void setColActionA(String colName,String actID) throws ErrorMessage{
		this.setColAction(colName,
				Window_Event.OnClick,
				Action_Type.NONE_POPE_SUBMIT,
				actID,
				null);
	}

	/**
	 * 设置表格列数据源为外部传入数据时列对象
	 * @param colName  列名,如果没有对应列抛出异常
	 * @param collComponent 外部传入对象  
	 * @throws ErrorMessage 
	 */
	public void setExtendCol(String colName,HtmlWindow... collComponent) throws ErrorMessage{
		_checkColName(colName);
		this.extentColumn.put(colName,collComponent);
		_setExtent(colName, true);
	}

	/**
	 * 设置列对象生成绑定器<br>
	 * <ul> 列对象绑定器由具体的业务组件生成器生成
	 * @param colName  列名
	 * @param callBack 列对象生成绑定器
	 * @throws ErrorMessage
	 */
	public void setCallBack(String colName,CallBack callBack) throws ErrorMessage{
		_checkColName(colName);
		columnCallBack.put(colName, callBack);
		_setExtent(colName, true);
	}

	/**
	 *  设置应用系统路径
	 * @param homeUrl
	 */
	public void setSHomeUrl(String homeUrl) {
		sHomeUrl = homeUrl;
	}

	/**
	 *  设置是否显示行下标
	 * @param displayRowIndex 是否显示行下标
	 * @throws ErrorMessage 
	 */
	public void setDisplayRowIndex(boolean displayRowIndex) throws ErrorMessage{
		this.putIndexCol();
	}
	
	/**
	 * 获取指定列的callback
	 * @param colName 列名
	 * @return 指定列的callback
	 */
	public CallBack getCallBack(String colName){
		return columnCallBack.getByKey(colName);
	}

	/**
	 * 返回列数
	 * @return
	 */
	public int getColNumber() {
		return this.tableColField.size();
	}

	/**
	 * 获取指定列是否是描述列
	 * @param col 列下标
	 * @return
	 * @throws ErrorMessage
	 */
	public boolean isDescCol(int col) throws ErrorMessage{
		_checkColIndex(col);
		switch (this.getTableColType(col)){
		case DESC_SHORT_TEXT:
		case DESC_LONG_TEXT:
		case DESC_TEXT:
		case DESC_ANCHOR:
		case DESC_LONG_ANCHOR:
		case DESC_SHORT_ANCHOR:
			return true&&(!isExtent(col));
		default:
			return false;
		}
	}

	/**
	 * 获取表格是否有描述列 (类型是描述列，且数据源不是外部传入列)
	 * @return
	 * @throws ErrorMessage
	 */
	public boolean haveDescCol() throws ErrorMessage{
		for(int i=0;i<this.getColNumber();i++){
			if(isDescCol(i)){
				return true;
			}
		}
		return false;
	}

	/**
	 * 返回指定列列名
	 * @param index 列序号
	 * @return
	 * @throws ErrorMessage 
	 */
	public String getColName(int col) throws ErrorMessage{
		_checkColIndex(col);
		return this.tableColField.get(col);
	}

	/**
	 * 返回指定列数据是否为数据集外数据
	 * @param colName 列名称
	 * @return
	 */
	public boolean isExtent(String colName){
		return isExtent.getByKey(colName);
	}

	/**
	 * 返回指定列数据是否为数据集外数据
	 * @param colName 列名称
	 * @return
	 * @throws ErrorMessage 
	 */
	public boolean isExtent(int iColIndex) throws ErrorMessage{
		return isExtent.getByKey(this.getColName(iColIndex));
	}

	/**
	 * 返回指定列类型
	 * @return
	 * @throws ErrorMessage 
	 */
	public Col_Content_Type getTableColType(int col) throws ErrorMessage {
		_checkColIndex(col);
		return this.tableColType.get(col);
	}

	/**
	 * 获取列数据位数据集外数据时列外部数据
	 * @param colName 列名
	 * @return
	 * @throws ErrorMessage
	 */
	public HtmlWindow[] getExtentColumn(String colName) throws ErrorMessage {
		_checkColName(colName);
		return extentColumn.getByKey(colName);
	}

	/**
	 * 获取指定行事件列表
	 * @param colName 行名
	 * @return
	 * @throws ErrorMessage
	 */
	public ArrayList<Window_Event> getEvent(String colName) throws ErrorMessage {
		_checkColName(colName);
		return columnEvent.getByKey(colName);
	}

	/**
	 * 获取指定行事件的附加参数
	 * @param colName 行名
	 * @return
	 * @throws ErrorMessage
	 */
	public ArrayList<String[]> getOtherParams(String colName) throws ErrorMessage {
		_checkColName(colName);
		return eventOtherParams.getByKey(colName);
	}

	/**
	 * 获取指定行事件目标容器
	 * @param colName 行名
	 * @return
	 * @throws ErrorMessage
	 */
	public ArrayList<String> getEventTarget(String colName) throws ErrorMessage {
		_checkColName(colName);
		return eventTarget.getByKey(colName);
	}

	/**
	 * 获取指定行事件对应脚本函数
	 * @param colName 行名
	 * @return
	 * @throws ErrorMessage
	 */
	public ArrayList<Action_Type> getEventFunction(String colName) throws ErrorMessage {
		_checkColName(colName);
		return eventFunction.getByKey(colName);
	}

	/**
	 * 获取指定行事件ActID
	 * @param colName 行名 
	 * @return
	 * @throws ErrorMessage
	 */
	public ArrayList<String> getEventAct(String colName) throws ErrorMessage {
		_checkColName(colName);
		return eventAct.getByKey(colName);
	}

	/**
	 * 获取指定列标题
	 * @param col 列序号
	 * @return
	 * @throws ErrorMessage 
	 */
	public String getTableColTitle(int col) throws ErrorMessage {
		_checkColIndex(col);
		return this.tableColTitle.get(col);
	}

	/**
	 * 获取指定列是否不显示重复数据
	 * @param colName 列名
	 * @return 是否不显示重复数据
	 * @throws ErrorMessage
	 */
	public boolean getDisRepeat(String colName){
		return this.displayDuplicateCol.getByKey(colName)==null?false:
			this.displayDuplicateCol.getByKey(colName);
	}

	/**
	 * @return 获取应用系统路径
	 */
	public String getSHomeUrl() {
		return sHomeUrl;
	}

	/**
	 * @return 获取用户信息
	 */
	public UserInfo getUser() {
		return mUser;
	}

	/**
	 * 设置表格列为外部传入时列内容
	 * @param sFieldName 列名,列名必须唯一,当表格绑定数据集时为要绑定的数据集列的列名
	 * @param fieldType  列类型
	 * @param sColTitle  列标题
	 * @param disRepeat  是否不显示当前列重复数据 true不显示,false显示
	 * @param collComponent 列内容(为html对象)
	 * @throws ErrorMessage 
	 */
	private void putCol(String sFieldName,Col_Content_Type fieldType,String sColTitle,
			boolean disRepeat,HtmlWindow...collComponent) throws ErrorMessage{
		this.tableColField.add(sFieldName);
		this.tableColType.add(fieldType);
		this.tableColTitle.add(sColTitle);
		this.displayDuplicateCol.put(sFieldName, disRepeat);
		if(collComponent==null||collComponent.length<1){
			_setExtent(sFieldName, false);
		}else{
			this.extentColumn.put(sFieldName, collComponent);
			_setExtent(sFieldName, true);
		}
	}
	
	/**
	 *  插入索引列
	 */
	private void putIndexCol() throws ErrorMessage{
		this.tableColField.add(0, this.INDEX_COL_NAME);
		this.tableColType.add(0,Col_Content_Type.NAME_TEXT);
		this.tableColTitle.add(0,"  ");
		this.setCallBack(this.INDEX_COL_NAME, new IndexColCallback());
		_setExtent(this.INDEX_COL_NAME, true);
	}

	/**
	 * 设置列动作要执行的JS函数
	 * @param colName       列名
	 * @param functionName  函数名
	 * @throws ErrorMessage
	 */
	private void setFunction(String colName,Action_Type functionName) throws ErrorMessage{

		/** 判断此列是否存在 */
		_checkColName(colName);

		ArrayList<Action_Type> func=null; 
		func=eventFunction.getByKey(colName);
		if(func==null){
			func=new ArrayList<Action_Type>();
		} 
		func.add(functionName);
		eventFunction.put(colName, func);
	}

	/**
	 * 设置列动作要执行的脚本的附加参数
	 * @param colName     列名
	 * @param otherParams 附加参数(可以多个)
	 * @throws ErrorMessage
	 */
	private void setOtherParams(String colName,String...otherParams) throws ErrorMessage{
		/** 判断此列是否存在 */
		_checkColName(colName);
		ArrayList<String[]> func=null; 
		func=eventOtherParams.getByKey(colName);
		if(func==null){
			func=new ArrayList<String[]>();
		} 
		func.add(otherParams);
		eventOtherParams.put(colName, func);
	}

	/**
	 * 设置列对象动作ID
	 * @param colName 列名
	 * @param actID   动作ID
	 * @throws ErrorMessage
	 */
	private void setAct(String colName,String... actID) throws ErrorMessage{
		/** 判断此列是否存在 */
		_checkColName(colName);
		ArrayList<String> act=null; 
		act=eventAct.getByKey(colName);
		if(act==null){
			act=new ArrayList<String>();
		} 
		TOOLS.stringArrayToList(act, actID);
		eventAct.put(colName, act);
	}

	/**
	 * 设置列对象需要触发的事件
	 * @param colName     列名
	 * @param event		  事件类型	
	 * @throws ErrorMessage
	 */
	private void setEvent(String colName,Window_Event... event) throws ErrorMessage{
		/** 判断此列是否存在 */
		_checkColName(colName);
		ArrayList<Window_Event> even=null; 
		even=columnEvent.getByKey(colName);
		if(even==null){
			even=new ArrayList<Window_Event>();
		}
		for(Window_Event e:event){
			even.add(e);
		}
		columnEvent.put(colName, even);
	}

	/**
	 * 设置列对象事件对应目标ID
	 * @param colName 列名
	 * @param targetID  目标ID
	 * @throws ErrorMessage 
	 */
	private void setTarget(String colName,String... targetID) throws ErrorMessage{
		/** 判断此列是否存在 */
		_checkColName(colName);
		ArrayList<String> target=null; 
		target=eventTarget.getByKey(colName);
		if(target==null){
			target=new ArrayList<String>();
		} 
		TOOLS.stringArrayToList(target, targetID);
		eventTarget.put(colName, target);
	}

	/**
	 * 初始化
	 * @throws ErrorMessage
	 */
	private void _init() throws ErrorMessage{
		this.tableColField=new ArrayList<String>();
		this.tableColType=new ArrayList<Col_Content_Type>();
		this.tableColTitle=new ArrayList<String>();
		this.extentColumn=new KvMap<String, HtmlWindow[]>();
		this.eventAct=new KvMap<String, ArrayList<String>>() ;
		this.columnEvent=new KvMap<String, ArrayList<Window_Event>>();
		this.eventTarget=new KvMap<String, ArrayList<String>>();
		this.eventFunction=new KvMap<String, ArrayList<Action_Type>>();
		this.eventOtherParams = new KvMap<String, ArrayList<String[]>>();
		this.isExtent=new KvMap<String, Boolean>();
		this.columnCallBack=new KvMap<String, CallBack>();
		this.displayDuplicateCol = new KvMap<String, Boolean>();
	}

	/**
	 * 设置表格列顺序和类型    
	 * @param tableFields     表格列顺序列表
	 * @param tableFieldsType 表格列类型顺序列表
	 * @throws ErrorMessage 
	 */
	private void setField(String[] tableFields,Col_Content_Type[] tableFieldsType) throws ErrorMessage{
		if(tableFields.length!=tableFieldsType.length){
			throw new ErrorMessage("列数大小不一致");
		}
		TOOLS.stringArrayToList(this.tableColField, tableFields);
		for(Col_Content_Type type:tableFieldsType){
			this.tableColType.add(type);
		}
		this.colNums=tableColField.size();
	}

	/**
	 * 默认所有列数据为数据集数据
	 * @throws ErrorMessage
	 */
	private void _initIsExtend() throws ErrorMessage{
		for(int i=0;i<colNums;i++){
			this._setExtent(getColName(i),false);
		}
	}

	/**
	 * 设置指定列数据源是否数据集数据,如果不是数据需要外部传入
	 * @param colName  列名
	 * @param isExtent 列的数据源是否数据集数据
	 * @throws ErrorMessage
	 */
	private void _setExtent(String colName,boolean isExtent) throws ErrorMessage{
		this.isExtent.put(colName,isExtent);
	}

	/**
	 * 判断列名对应列是否存在
	 * @param colName
	 * @throws ErrorMessage
	 */
	private void _checkColName(String colName) throws ErrorMessage{
		if(tableColField.indexOf(colName)==-1){
			throw new ErrorMessage("The column "+colName+" not exist!");
		}
	}

	/**
	 * 判断列序号是否越界
	 * @param col 列序号
	 * @throws ErrorMessage 
	 */
	private void _checkColIndex(int col) throws ErrorMessage{
		if(col>getColNumber()-1){
			throw new ErrorMessage("The column number "+col+" is out of bound!");
		}
	}
}
